package com.wkbb.basic.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wkbb.basic.feign.TcCloudFeignService;
import com.wkbb.basic.feign.WxFeignService;
import com.wkbb.basic.mapper.UserMapper;
import com.wkbb.basic.mapper.VisitorMapper;
import com.wkbb.basic.model.Organization;
import com.wkbb.common.dto.basic.VisitorInviteDto;
import com.wkbb.common.dto.basic.VisitorUserDto;
import com.wkbb.basic.service.OrganizationService;
import com.wkbb.basic.service.VisitorService;
import com.wkbb.common.base.BaseServiceImpl;
import com.wkbb.basic.model.*;
import com.wkbb.basic.service.*;
import com.wkbb.basic.utils.FileUtil;
import com.wkbb.basic.utils.ImageOfbase64UtilDto;
import com.wkbb.basic.utils.VisitorUtil;
import com.wkbb.basic.utils.WebankUtil;
import com.wkbb.common.config.ServiceConfig;
import com.wkbb.common.constants.Constants;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.dto.ResultDTO;
//import com.wkbb.basic.vo.ValidVisitorDeviceUserVo;
import com.wkbb.common.dto.basic.UserDto;
import com.wkbb.common.dto.sms.SmsDto;
import com.wkbb.common.dto.wx.AccountDto;
import com.wkbb.common.enums.EntranceEnum;
import com.wkbb.common.utils.ObjectUtil;
import com.wkbb.common.utils.TimeUtil;
import com.wkbb.common.utils.UuIdUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author caohongdan
 * @date 2020/8/5
 * @description
 */
@Slf4j
@Service
public class VistitorServiceImpl extends BaseServiceImpl<VisitorInviteDto> implements VisitorService {

    @Autowired
    private VisitorMapper visitorMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private TcCloudFeignService tcCloudFeignService;

    @Autowired
    private UserOpenService userOpenService;

    @Autowired
    private YouTuService youTuService;

    @Autowired
    private WebankService webankService;

    @Autowired
    private WxFeignService wxFeignService;

    @Autowired
    @Lazy
    private XmppService xmppService;

    @Autowired
    private ServiceConfig serviceConfig;

    private void setVisitorInvite(List<VisitorInviteDto> list){
        log.info("-----------VisitorInvite列表--------:{}",list);
        for(VisitorInviteDto visitorInvite: list){
            List<VisitorUserDto> visitorUserInfo =  visitorMapper.getVisitorUserInfo(visitorInvite.getId());
            visitorInvite.setInviteList(visitorUserInfo);
        }
    }
    private ResultDTO<Object> addUserFace(Long orgId, String faceImg, Long userId){
        try {
            ResultDTO<AccountDto> result = wxFeignService.getAccountByOrg(orgId);
            log.info("----------人脸添加 addUserFace----------userId:{},orgId:{},faceImg:{},result:{}",userId,orgId,faceImg,result);
            if (ResultDTO.checkSuccess(result) && result.getData() != null) {
                Long accountId = result.getData().getId();
                String userCode = UuIdUtil.getUserCodeByUUId();
                String url = youTuService.changeUrl(faceImg);

//            添加人脸
                return   webankService.addWeBankUserFace(url, userCode, orgId, accountId, userId, EntranceEnum.MINI.getValue(), null);
            }
            return null;
        }catch (Exception e){
            log.error("**********添加人脸 addUserFace**********",e);
            return null;
        }
    }

    @Override
    public ResultDTO addVisitor(VisitorInviteDto visitorInviteDto) throws Exception{
        List<VisitorUserDto> inviteList = visitorInviteDto.getInviteList();
        log.info("----------新建邀约--访客用户查询-----------inviteList:{}",inviteList);
//        获取访客的用户Id
        List<UserDto> userList= new ArrayList<>();
        // 判端是否为空
        if (CollectionUtils.isNotEmpty(inviteList)) {
            // 进行拆解封装
            userList = inviteList.stream().map(invite -> {
                UserDto userDto = new UserDto();
                BeanUtils.copyProperties(invite, userDto);
                return userDto;
            }).collect(Collectors.toList());
        }
        List<UserDto> visitUser = userOpenService.getVisitUser(userList);
//        保存用户Id到访客数组
        if(null!=visitUser){
            for (int i=0; i<inviteList.size();i++){
                for (int j=0; j<visitUser.size();j++){
                    if(inviteList.get(i).getMobile() == visitUser.get(j).getMobile()){
                        inviteList.get(i).setUserId(visitUser.get(j).getId());
                    }
                }
            }
        }else{
            return new ResultDTO<>(ErrorCode.BUSINESS_DATA_GET_ERROR);
        }
        log.info("----------新建邀约--访客用户查询2222222-----------inviteList:{}",inviteList);
        /**
         * 新建邀约:邀约记录表数据插入
         * */
        log.info("----------新建邀约 start：addVisitor-----------");
//        判断新建邀约状态
        Short status = VisitorUtil.visitorStatus(visitorInviteDto.getBeginTime(), visitorInviteDto.getEndTime());
//        获取学校信息
        Organization organization = organizationService.getByPrimaryKey(visitorInviteDto.getOrgId());
        String addressStr = ObjectUtil.getObject(organization.getProvince()).toString() + ObjectUtil.getObject(organization.getCity()).toString() + ObjectUtil.getObject(organization.getArea()).toString() + ObjectUtil.getObject(organization.getAddress()).toString();
        String orgName = organization.getName();
//        第三方访客系统标识
        String extendArrangeNo = visitorInviteDto.getExtendArrangeNo() ;
        if(null == extendArrangeNo){
            extendArrangeNo = "";
        }
        if(null == visitorInviteDto.getExtendId()){
            visitorInviteDto.setExtendId((short) 0);
        }

        Date beginTime = visitorInviteDto.getBeginTime();
        Date endTime = visitorInviteDto.getEndTime();

        VisitorInviteDto visitorInvite = new VisitorInviteDto();
        visitorInvite.setUserId(visitorInviteDto.getUserId());
        visitorInvite.setOrgId(visitorInviteDto.getOrgId());
        visitorInvite.setOrgName(orgName);
        visitorInvite.setInviteName(visitorInviteDto.getInviteName());
        visitorInvite.setInviteMobile(visitorInviteDto.getInviteMobile());
        visitorInvite.setInviteAddress(addressStr);
        visitorInvite.setVisitType(visitorInviteDto.getVisitType());
        visitorInvite.setVisitTimes(visitorInviteDto.getVisitTimes());
        visitorInvite.setBeginTime(beginTime);
        visitorInvite.setEndTime(endTime);
        visitorInvite.setStatus(status);
        visitorInvite.setExtendArrangeNo(extendArrangeNo);
        visitorInvite.setExtendId(visitorInviteDto.getExtendId());

        visitorMapper.addVisitor(visitorInvite);
        log.info("----------新建邀约 end：addVisitor-----------");
        Long visitId = visitorInvite.getId();

        VisitorUserDto visitorUser = new VisitorUserDto();

        Short status2 = 7;

        for (int i=0; i<inviteList.size();i++){
            log.info("----------新建访客用户 start：addVisitor--addVisitorUser-----------name:{}",inviteList.get(i).getName());
            visitorUser.setInviteId(visitId);
            visitorUser.setName(inviteList.get(i).getName());
            visitorUser.setMobile(inviteList.get(i).getMobile());
            visitorUser.setUserId(inviteList.get(i).getUserId());
            visitorUser.setBeginTime(beginTime);
            visitorUser.setEndTime(endTime);
            visitorUser.setStatus(status2);
            visitorUser.setExtendArrangeNo(extendArrangeNo);
            visitorUser.setExtendId(visitorInviteDto.getExtendId());
            visitorUser.setAreaId(inviteList.get(i).getAreaId());

            if(visitorInviteDto.getExtendId()  == 1){
                if(inviteList.get(i).getFaceImg() != null){
                    //添加人脸
                    ResultDTO resultFace = addUserFace(visitorInviteDto.getOrgId(),inviteList.get(i).getFaceImg(),inviteList.get(i).getUserId());
                    if (!ResultDTO.checkSuccess(resultFace) ) {
                        log.info("----------三方腾讯访客未添加成功的人脸----------userId:{},getFaceImg:{}",visitorUser.getUserId(),visitorUser.getFaceImg());
                    }else{
                        status2 = 6;
                        visitorUser.setStatus(status2);
                    }
                }

            }
            visitorMapper.addVisitorUser(visitorUser);
            log.info("----------新建访客用户 end：addVisitor--addVisitorUser-----------");
            Long orgId = visitorInviteDto.getOrgId();
            if(visitorInviteDto.getExtendId()  != 1){
                //发送短信给邀请的访客用户
                SmsDto smsDto = new SmsDto();
                List<String> mobileList = Arrays.asList(inviteList.get(i).getMobile());
                String addVisitorInfo = VisitorUtil.visitorEvn(serviceConfig.getProfilesActive()) + visitorUser.getId() ;
                List<String> paramsList = Arrays.asList(inviteList.get(i).getName(),orgName,addVisitorInfo);
                int templateId = 613021;
                smsDto.setMobileList(mobileList);
                smsDto.setOrgId(orgId);
                smsDto.setParamsList(paramsList);
                smsDto.setTemplateId(templateId);
                log.info("--------addVisitor--访客用户短信推送:sendSms-----------,smsDto;{}", smsDto);
                tcCloudFeignService.sendSms(smsDto);
            }

            //访客状态变为：5:已通行 6:已登记 7:未登记  时，推送访客信息给设备
            Map<String, Object> params = new HashMap<>(1);
            params.put("inviteId", visitorInvite.getId());
//            List<ValidVisitorDeviceUserVo> validVisitorDeviceUserVoList = userMapper.getValidVisitorDeviceUserByDeviceOrg(params);
//            validVisitorDeviceUserVoList.forEach(validVisitorUserDto->{
//                    xmppService.updateValidVisitorUser(orgId,null,validVisitorUserDto,false);
//                }
//            );
        }
        return new ResultDTO<>();
    }


    @Override
    public ResultDTO addVisitorUser(VisitorUserDto visitorUser) throws Exception {
        /**
         * 添加访客人脸等信息
         * */
        log.info("***********添加访客身份证人脸:addVisitorUser******id:{}}", visitorUser.getId());

        Short status = 6;
        visitorUser.setStatus(status);
        if(visitorUser.getFaceImg() != null){
            //添加人脸
            ResultDTO resultFace = addUserFace(visitorUser.getOrgId(),visitorUser.getFaceImg(),visitorUser.getUserId());
            if (!ResultDTO.checkSuccess(resultFace)) {
                log.info("----------未添加成功的人脸----------userId:{},getFaceImg:{}",visitorUser.getUserId(),visitorUser.getFaceImg());
                return new ResultDTO<>(ErrorCode.ERRROR_WEBANKAPPID);
            }else{
                visitorMapper.updateVisitorUser(visitorUser);
            }
        }else{
            visitorMapper.updateVisitorUser(visitorUser);
        }


        //访客状态变为：5:已通行 6:已登记 7:未登记  时，推送访客信息给设备
        Map<String, Object> params = new HashMap<>(1);
        params.put("inviteId", visitorUser.getInviteId());
//        List<ValidVisitorDeviceUserVo> validVisitorDeviceUserVoList = userMapper.getValidVisitorDeviceUserByDeviceOrg(params);
//        validVisitorDeviceUserVoList.forEach(validVisitorUserDto->{
//                    xmppService.updateValidVisitorUser(visitorUser.getOrgId(),null,validVisitorUserDto,false);
//                }
//        );
        return new ResultDTO<>();
    }

    @Override
    public void updateVisitorUser(VisitorUserDto visitorUser) throws Exception{
        visitorMapper.updateVisitorUser(visitorUser);
    }

    @Override
    public PageInfo<VisitorInviteDto> getVisitorList(Map<String, Object> params, Integer pageNo, Integer pageSize )throws Exception {
        try{
            if (pageNo == null || pageSize == null) {
                return null;
            }
            Page<VisitorInviteDto> page = PageHelper.startPage(pageNo, pageSize, true);
            List<VisitorInviteDto> visitorInviteList = visitorMapper.getVisitorList(params);
            for (int i=0; i<visitorInviteList.size();i++){
                if(visitorInviteList.get(i).getStatus() == 4 || visitorInviteList.get(i).getStatus() == 1 ){
                    Short status = VisitorUtil.visitorStatus(visitorInviteList.get(i).getBeginTime(), visitorInviteList.get(i).getEndTime());
                    visitorInviteList.get(i).setStatus(status);
                }
            }
            PageInfo<VisitorInviteDto> pageInfo = new PageInfo<VisitorInviteDto>(visitorInviteList);
            setVisitorInvite(pageInfo.getList());
            pageInfo.setTotal(page.getTotal());
            return pageInfo;
        }catch (Exception e){
            log.error("**********获取邀约访客列表异常**********",e);
//            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
        return null;
    }


    @Override
    public void cancelVisitor(Long id) throws Exception {

//        取消邀约
        visitorMapper.cancelVisitor(id);
        visitorMapper.cancelVisitorUser(id);
//        删除人脸
        VisitorInviteDto visitorInvite = visitorMapper.getVisitorInvite(id);
        List<VisitorUserDto> visitorUserInfo =  visitorMapper.getVisitorUserInfo(id);
        for(VisitorUserDto visitorUser: visitorUserInfo){
            if(isDeleteVisitorFace(visitorUser)){
                deleteVisitorFace(visitorInvite.getOrgId(),visitorUser.getUserId());
            }
        }
        return;
    }

//    @Override
//    public List<ValidVisitorDeviceUserVo> getValidVisitorUserList(Map<String, Object> params)  {
//        return userMapper.getValidVisitorDeviceUserByDeviceOrg(params);
//    }


    @Override
    public VisitorInviteDto getVisitUserDetails(Long visitorId) throws Exception{
        log.info("*********** 获取访客的邀约信息 getVisitUserDetails*************");
        VisitorUserDto visitorUserInfo =  visitorMapper.getVisitUserDetails(visitorId);
        VisitorInviteDto visitorInvite = visitorMapper.getVisitorInvite(visitorUserInfo.getInviteId());

        if(visitorInvite.getStatus() == 4 || visitorInvite.getStatus() == 1 ){
            Short status = VisitorUtil.visitorStatus(visitorInvite.getBeginTime(), visitorInvite.getEndTime());
            visitorInvite.setStatus(status);
        }

        Long userId = visitorUserInfo.getUserId();
        Long orgId = visitorInvite.getOrgId();
        List<YoutuFace> youtuFaceList = youTuService.selectFaceByuserCode(userId,orgId);
        if (CollectionUtils.isNotEmpty(youtuFaceList)) {
            visitorUserInfo.setFaceImg(youtuFaceList.get(0).getWebUrl());
        }

        List<VisitorUserDto> visitorUserList = new ArrayList<>();
        visitorUserList.add(visitorUserInfo);
        visitorInvite.setInviteList(visitorUserList);

        return visitorInvite;
    };

    @Override
    public void updateVisitorStatus(){
//        定时器处理新建邀约状态
        //获取状态是1：进行中,4: 未到访
        List<VisitorInviteDto> visitorList = visitorMapper.getVisitorStatus();
        log.info("***********获取到需要访客状态updateVisitorStatus******visitorList:{}", visitorList);
        for (VisitorInviteDto visitorInvite : visitorList) {
            // 状态(1:进行中 2:已取消 3:已过期 4: 未到访 5: 已到访)
            Short status = visitorInvite.getStatus();
            Short statusInfo = VisitorUtil.visitorStatus(visitorInvite.getBeginTime(),visitorInvite.getEndTime());
            log.info("***********获取到需要访客状态----------------******visitorInvite-{}", visitorInvite);

            if(!status.equals(statusInfo)){
//                邀约已过期删除人脸
                if(statusInfo == 3){
                    List<VisitorUserDto> visitorUserInfo =  visitorMapper.getVisitorUserInfo(visitorInvite.getId());
                    for(VisitorUserDto visitorUser: visitorUserInfo){
                        try {
                            if(isDeleteVisitorFace(visitorUser)){
                                deleteVisitorFace(visitorInvite.getOrgId(),visitorUser.getUserId());
                            }
                        }catch (Exception e){
                            log.error("----------定时器处理新建邀约状态:删除人脸异常----------",e);
                        }
                    }
                }
                log.info("***********获取到需要访客状态******visitorInvite-{},status:{},status2:{}", visitorInvite,status,statusInfo);


                Map<String, Object> params = new HashMap<>(2);
                params.put("id", visitorInvite.getId());
                params.put("status", statusInfo);
                visitorMapper.updateVisitorStatus(params);
            }
        }
    };

    private boolean isDeleteVisitorFace(VisitorUserDto visitorUser)throws Exception{
        //判断是否要调接口人脸接口 -- 腾讯三方访客直接调删除人脸接口
        boolean flag = true;
            //访客小程序的邀约当前时间之后还有没有邀约订单
            List<VisitorUserDto> visitorUserAccessTime = visitorMapper.getVisitorUserAccessTime(visitorUser.getUserId());
            int size = visitorUserAccessTime.size();
            if(size>0){
                flag = false;
            }
        return flag;
    }

    @Override
    public void deleteVisitorFace(Long orgId,Long userId) throws Exception{

        try{
             Boolean flag = userOpenService.getUserRoleById(orgId, userId);

             if(!flag){
                 YoutuPerson youtuPerson = youTuService.getYoutuPerson(orgId, userId);
                 if(null!=youtuPerson){
                     webankService.modifyFace(youtuPerson.getPersonId(),orgId,true,null,null,null);
                 }
             }
        }catch (Exception e){
            log.error("----------删除邀约人脸异常----------",e);
        }
    }


    @Override
    public ResultDTO addVisitorThird(VisitorInviteDto visitorInviteDto) throws Exception{
        try{

            Short visitType = 1;
            Short visitTimes = 2;
            visitorInviteDto.setVisitType(visitType);
            visitorInviteDto.setVisitTimes(visitTimes);
            if(null != visitorInviteDto.getStatus() && visitorInviteDto.getStatus() != 2 ){
                visitorInviteDto.setStatus(VisitorUtil.visitorStatus(visitorInviteDto.getBeginTime(), visitorInviteDto.getEndTime()));
            }
            List<VisitorUserDto> inviteList = visitorInviteDto.getInviteList();
            log.info("************* 三方腾讯添加访客邀约  ***************:{}", visitorInviteDto);
            VisitorInviteDto visitorInviteInfo = visitorMapper.getThirdVisitorInvite(visitorInviteDto.getExtendArrangeNo());
            //邀约记录是否已存储
            if(null != visitorInviteInfo){
//                更新邀约列表信息
                visitorMapper.updateThirdVisitorInvite(visitorInviteDto);
                List<VisitorUserDto> inviteList2 = visitorInviteDto.getInviteList();
//                log.info("----------新建邀约--访客用户查询-----------inviteList:{}",inviteList2);
//              获取访客的用户Id
                List<UserDto> userList2= new ArrayList<>();
                // 判端是否为空
                if (CollectionUtils.isNotEmpty(inviteList2)) {
                    // 进行拆解封装
                    userList2 = inviteList2.stream().map(invite -> {
                        UserDto userDto = new UserDto();
                        BeanUtils.copyProperties(invite, userDto);
                        return userDto;
                    }).collect(Collectors.toList());
                }
                List<UserDto> visitUser2 = userOpenService.getVisitUser(userList2);
                Long userId = null;
                if(null!=visitUser2){
                    userId = visitUser2.get(0).getId();
                }
                Long orgId = visitorInviteDto.getOrgId();
                //                更新访客信息
                VisitorUserDto visitorUserDetail =  visitorInviteDto.getInviteList().get(0);
                if(userId != null){
                    List<YoutuFace> youtuFaceList = youTuService.selectFaceByuserCode(userId,orgId);
                    log.info("是否有人脸：{},判断：{}", youtuFaceList,CollectionUtils.isNotEmpty(youtuFaceList) && youtuFaceList.get(0).getWebUrl() != null);

                    if (CollectionUtils.isNotEmpty(youtuFaceList) && youtuFaceList.get(0).getWebUrl() != null) {
                        //已经有人脸
                        if(visitorInviteDto.getStatus() == 2){
//                          取消邀约 -- 删除人脸
                            cancelVisitor(visitorInviteInfo.getId());
                        }
                    }else if(visitorInviteDto.getStatus() == null){
                        //添加人脸
                        ResultDTO resultFace = addUserFace(orgId,visitorInviteDto.getInviteList().get(0).getFaceImg(),userId);
                       if (!ResultDTO.checkSuccess(resultFace)) {
                                log.info("----------更新三方访客人脸 未添加成功的人脸 addVisitorThird----------userId:{},getFaceImg:{}",userId,visitorInviteDto.getInviteList().get(0).getFaceImg());
                        }else{
                           Short status = 6;
                           visitorUserDetail.setStatus(status);
                       }

                    }
                }

                visitorUserDetail.setExtendArrangeNo(visitorInviteDto.getExtendArrangeNo());
                visitorUserDetail.setBeginTime(visitorInviteDto.getBeginTime());
                visitorUserDetail.setEndTime(visitorInviteDto.getEndTime());
                visitorMapper.updateThirdVisitorUser(visitorUserDetail);
            }else{
                //        获取邀约人的用户Id
                List<UserDto> userList= new ArrayList<>();
                // 判端是否为空
                if (CollectionUtils.isNotEmpty(inviteList)) {
                    // 进行拆解封装
                    userList = inviteList.stream().map(invite -> {
                        UserDto userDto = new UserDto();
                        BeanUtils.copyProperties(invite, userDto);
                        return userDto;
                    }).collect(Collectors.toList());
                }
                List<UserDto> visitUser = userOpenService.getVisitUser(userList);

                if(null!=visitUser){
                    visitorInviteDto.setUserId(visitUser.get(0).getId());
                }

//                添加邀约信息
                return addVisitor(visitorInviteDto);
            }
            return new ResultDTO();
        }catch (Exception e){
            log.error("**********三方腾讯添加访客邀约异常**********",e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @Override
    public void visitorRecord(Long userId,Long attTime,String deviceCode,Long areaId) throws Exception{

        try{

            VisitorUserDto visitorUserDto = new VisitorUserDto();
            visitorUserDto.setUserId(userId);
            visitorUserDto.setAreaId(areaId);
            log.info("************* 上报数组参数  ***************:{}", visitorUserDto);
            List<VisitorUserDto> visitorUserAccessList = visitorMapper.getVisitorUserAccess(visitorUserDto);

            if(visitorUserAccessList.size() == 0){
                visitorUserDto.setAreaId(null);
                visitorUserAccessList = visitorMapper.getVisitorUserAccess(visitorUserDto);
            }

            log.info("************* 上报数组  ***************:{}",visitorUserAccessList);
            for(VisitorUserDto visitorUser:visitorUserAccessList){
                long time = visitorUser.getBeginTime().getTime();
                long time1 = visitorUser.getEndTime().getTime();


                if( time<= attTime && time1>=attTime ){
                    if(visitorUser.getExtendId() == 1){
                        log.info("************* 上报数组成功  ***************:{},attTick{},deviceCode{}",visitorUser.getExtendArrangeNo(),attTime/1000,deviceCode);
                        //三方腾讯访客上报
                    tcCloudFeignService.thirdVisitorRecord(deviceCode, "PASS", "FACE", attTime/1000, visitorUser.getExtendArrangeNo());
                    }
                    if(visitorUser.getStatus() != 5){
                        VisitorUserDto visitorUserInfo = new VisitorUserDto();
                        Short status = 5;
                        visitorUserInfo.setStatus(status);
                        visitorUserInfo.setId(visitorUser.getId());
                        visitorMapper.updateVisitorUser(visitorUserInfo);
                    }
                }

            }
        }catch (Exception e){
            log.error("----------访客人脸上报----------",e);
        }
    }
}
